package com.gitee.cui.server.handler;

import com.gitee.cui.common.cocurrent.CallbackTask;
import com.gitee.cui.common.cocurrent.CallbackTaskScheduler;
import com.gitee.cui.common.common.bean.msg.ProtoMsg;
import com.gitee.cui.server.processor.LoginProcessor;
import com.gitee.cui.server.server.ServerSession;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 登录请求处理类
 *
 * @author cuiqingqiang
 * @version 1.0
 * @date 2021-10-27 23:10
 **/
@Slf4j
@ChannelHandler.Sharable
@Service
public class LoginRequestHandler extends ChannelInboundHandlerAdapter {

	@Autowired
	private LoginProcessor loginProcessor;

	@Autowired
	private ChatRedirectHandler chatRedirectHandler;

	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		log.info("收到一个新的连接，但是没有登录 {}", ctx.channel().id());
		super.channelActive(ctx);
	}

	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
		if (!(msg instanceof ProtoMsg.Message)) {
			super.channelRead(ctx, msg);
			return;
		}

		ProtoMsg.Message message = (ProtoMsg.Message) msg;
		ProtoMsg.HeadType type = message.getType();
		if (loginProcessor.type() != type) {
			super.channelRead(ctx, msg);
			return;
		}

		ServerSession session = new ServerSession(ctx.channel());

		// 异步任务，处理登陆的逻辑
		CallbackTaskScheduler.add(new CallbackTask<Boolean>() {
			@Override
			public Boolean execute() throws Exception {
				return loginProcessor.action(session, message);
			}

			@Override
			public void onBack(Boolean success) {
				if (success) {
					ctx.pipeline().addAfter("login", "chat", chatRedirectHandler);
					ctx.pipeline().addAfter("login", "heartBeat", new HeartBeatServerHandler());
					ctx.pipeline().remove("login");
					log.info("登陆成功：{}", session.getUser());
				} else {
					// 登录失败，清除session信息
					ServerSession.closeSession(ctx);
					log.info("登录失败：{}", session.getUser());
				}
			}

			@Override
			public void onException(Throwable t) {
				// 发生异常，清楚session信息
				ServerSession.closeSession(ctx);
				log.info("登录失败：{}", session.getUser());
			}
		});
	}
}
